#ifndef __INTERPRETE_H
#define __INTERPRETE_H

   #include <stdio.h>
   #include <stdlib.h>

   enum op { LOAD = 0 , LOADA, LOADI, LOADL, STORE, STOREI, CALL,CALLI, RET, PUSH, POP, JUMP, JUMPI, JUMPIF, HALT };

   enum r { CB = 0, CT, PB, PT, SB, ST, HB, HT,
         LB, L1, L2, L3, L4, L5, L6, PC };
   enum prim {_ID = 1,_NOT,_AND,_OR,_INC,_DEC,_NEG,_ADD,_SUB,_MULT,_DIV,_MOD,
              _LT,_LE,_GT,_GE,_EQ,_NE,_TO21,_TO22,_NEW,_FREE,_GET,_PUT};
   int codigo[1024];
   int pila[1024];
   int registros[16];





void emit(int op, int r, int n, int d);

//directivas
void inc();

void mult();

void get();

void put();





//carga un objeto de n palabras desde la dirección (d + registro r) y lo empuja en la pila
void load(int n,int d, int r);

//empuja la direccion del dato(d + registro r) en la pila
void loada(int d,int r);

//saca una direccion de la pila, carga un objeto de n palabras desde esa direccion y lo empuja en la pila
void loadi(int n);

//empuja en la pila el literal d (1 palabra)
void loadl(int d);

//saca un objeto de tamaño n de la pila y lo almacena en la direccion (d + registro r)
void store(int n,int d, int r);

//saca un objeto de tamaño n de la pila, entonces, saca una direccion y almacena el objeto en la direccion
void storei(int n);

//llama a la rutina cuya direccion es(d + registro r), usando la direccion en el registro n como enlace estatico
void call(int n,int d, int r);

//saca de la pila el enlace estatico y la direccion de comienzo de la rutina y la llama
void calli();

//retorna de la rutina actual: saca de la pila un resultado de tamaño n, elimina el registro de activacion del tope,elimina las d palabras de los parametros, y entonces empuja el resultado a devolver en la pila
void Return(int n,int d);

//empuja d palabras sin inicializar en la pila
void push(int d);

//saca un resultado de n palabras de la pila, a continuacion, saca d palabras mas de la misma, y entonces empuja el resultado de nuevo en la pila
void pop(int n,int d);

//salta a la direccion de codigo (d + registro r)
void jump(int d,int r);

//saca de la pila una direccion de codigo y salta a la misma
void jumpi();

//saca una palabra de la pila y salta a la direccion de codigo (d + registro r) si y solo si, ese valor es igual a n
void jumpif(int n,int d, int r);

//detiene la ejecucion del programa
void halt();

void interpreta();

void imprime_pila();

void imprime_codigo();

#endif

